<?php

namespace app\admin\controller\auth;

use app\admin\model\AuthGroup;
use app\admin\model\AuthGroupAccess;
use app\common\controller\Backend;
use fast\Random;
use fast\Tree;
use think\Db;
use think\Validate;

/**
 * 管理员管理
 *
 * @icon   fa fa-users
 * @remark 一个管理员可以有多个角色组,左侧的菜单根据管理员所拥有的权限进行生成
 */
class Admin extends Backend
{
    /**
     * 无需登录的方法,用于AJAX验证
     */
    protected $noNeedLogin = ['checkUsername', 'checkMobile','generateOcationByNickname'];

    /**
     * 无需权限的方法,用于AJAX验证
     */
    protected $noNeedRight = ['checkUsername', 'checkMobile','generateOcationByNickname'];

    /**
     * @var \app\admin\model\Admin
     */
    protected $model = null;
    protected $selectpageFields = 'id,username,nickname,avatar';
    protected $searchFields = 'id,username,nickname';
    protected $childrenGroupIds = [];
    protected $childrenAdminIds = [];
    public $school_name='';

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('Admin');

        $this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
        $this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);

        $groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();

        Tree::instance()->init($groupList);
        $groupdata = [];
        if ($this->auth->isSuperAdmin()) {
            $result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
            foreach ($result as $k => $v) {
                $groupdata[$v['id']] = $v['name'];
            }
        } else {
            // 获取当前用户的用户组
            $currentUserGroups = $this->auth->getGroups();
            $allowedGroupIds = [];

            // 直接从数据库查询子组，避免Tree实例问题
            foreach ($currentUserGroups as $currentGroup) {
                // 添加当前用户组（同级）
                $allowedGroupIds[] = $currentGroup['id'];

                // 从groupList中查找直接子组
                foreach ($groupList as $group) {
                    if ($group['pid'] == $currentGroup['id']) {
                        $allowedGroupIds[] = $group['id'];
                    }
                }
            }

            // 去重并过滤
            $allowedGroupIds = array_unique($allowedGroupIds);
            $allowedGroupIds = array_intersect($allowedGroupIds, $this->childrenGroupIds);

            // 构建分组数据 - 简化逻辑
            $result = [];
            foreach ($currentUserGroups as $currentGroup) {
                $temp = [];

                // 添加当前组
                if (in_array($currentGroup['id'], $allowedGroupIds)) {
                    $temp[$currentGroup['id']] = $currentGroup['name'];
                }

                // 添加子组
                foreach ($groupList as $group) {
                    if ($group['pid'] == $currentGroup['id'] && in_array($group['id'], $allowedGroupIds)) {
                        $temp[$group['id']] = $group['name'];
                    }
                }

                if (!empty($temp)) {
                    $result[__($currentGroup['name'])] = $temp;
                }
            }

            // 如果结果为空，至少显示当前用户组
            if (empty($result) && !empty($currentUserGroups)) {
                $temp = [];
                foreach ($currentUserGroups as $currentGroup) {
                    if (in_array($currentGroup['id'], $this->childrenGroupIds)) {
                        $temp[$currentGroup['id']] = $currentGroup['name'];
                    }
                }
                if (!empty($temp)) {
                    $result['当前权限组'] = $temp;
                }
            }

            $groupdata = $result;
        }

        $this->view->assign('groupdata', $groupdata);
        //$this->assignconfig("admin", ['id' => $this->auth->id]);
        $this->assign('admin', $_SESSION['think']['admin']);
        $this->assignconfig('admin', $_SESSION['think']['admin']);
    }

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $childrenGroupIds = $this->childrenGroupIds;
            $groupName = AuthGroup::where('id', 'in', $childrenGroupIds)
                ->column('id,name');
            $authGroupList = AuthGroupAccess::where('group_id', 'in', $childrenGroupIds)
                ->field('uid,group_id')
                ->select();

            $adminGroupName = [];
            foreach ($authGroupList as $k => $v) {
                if (isset($groupName[$v['group_id']])) {
                    $adminGroupName[$v['uid']][$v['group_id']] = $groupName[$v['group_id']];
                }
            }
            $groups = $this->auth->getGroups();
            foreach ($groups as $m => $n) {
                $adminGroupName[$this->auth->id][$n['id']] = $n['name'];
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            // 获取当前用户信息
            $currentUser = $this->auth->getUserInfo();

            // 构建查询条件
            $query = $this->model->where($where);

            // 如果不是超级管理员，需要根据学校ID和用户组层级过滤
            if (!$this->auth->isSuperAdmin()) {
                // 获取当前用户的用户组
                $currentUserGroups = $this->auth->getGroups();
                $currentGroupIds = array_column($currentUserGroups, 'id');

                // 获取当前用户组及其下级用户组
                $allowedGroupIds = [];
                foreach ($currentGroupIds as $groupId) {
                    // 添加当前用户组（本级）
                    $allowedGroupIds[] = $groupId;

                    // 添加下级用户组
                    $childGroups = Db::name('auth_group')->where('pid', $groupId)->column('id');
                    $allowedGroupIds = array_merge($allowedGroupIds, $childGroups);
                }
                $allowedGroupIds = array_unique($allowedGroupIds);

                // 获取这些用户组的管理员ID
                $allowedAdminIds = Db::name('auth_group_access')
                    ->where('group_id', 'in', $allowedGroupIds)
                    ->column('uid');

                if (!empty($allowedAdminIds)) {
                    $query = $query->where('id', 'in', $allowedAdminIds);
                }

                // 额外的学校/社区过滤
                if (!empty($currentUser['school_id'])) {
                    // 学校管理员：显示同一学校的管理员（本级和下级）
                    $query = $query->where('school_id', $currentUser['school_id']);
                } elseif (!empty($currentUser['community_id'])) {
                    // 社区管理员：显示同一社区下所有学校的管理员（本级和下级）
                    $schoolIds = Db::name('eb_school')
                        ->where('community_id', $currentUser['community_id'])
                        ->column('id');
                    if (!empty($schoolIds)) {
                        $query = $query->where(function($query) use ($currentUser, $schoolIds) {
                            $query->where('school_id', 'in', $schoolIds)
                                  ->whereOr('community_id', $currentUser['community_id']);
                        });
                    } else {
                        // 如果没有找到学校，只显示同一社区的管理员
                        $query = $query->where('community_id', $currentUser['community_id']);
                    }
                }
            }

            $list = $query
                ->field(['password', 'salt', 'token'], true)
                ->order($sort, $order)
                ->paginate($limit);
            $this->model->getLastSql();
            foreach ($list as $k => &$v) {
                $groups = isset($adminGroupName[$v['id']]) ? $adminGroupName[$v['id']] : [];
                $v['groups'] = implode(',', array_keys($groups));
                $v['groups_text'] = implode(',', array_values($groups));
                $list[$k]['school_id']=model('School')->getSchool_idTextAttr($list[$k]['school_id'],$list[$k]);
                $list[$k]['community_id']=model('Community')->getCommunity_idTextAttr($list[$k]['community_id'],$list[$k]);
            }
            unset($v);
            $result = array("total" => $list->total(), "rows" => $list->items());
            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            $group = $this->request->post("group/a");
            if ($params) {
                // 如果昵称为空，则用用户名
                if (empty($params['nickname']) && !empty($params['username'])) {
                    $params['nickname'] = $params['username'];
                }
                Db::startTrans();
                try {

                    //检查用户类型如果是学校管理员，并且model('AuthGroupAccess')该学校已经有了管理员，并且超过了11个，就不能再添加了，就不能添加了
                    if (isset($group) && in_array(3, $group)) {
                        $count = model('AuthGroupAccess')
                            ->alias('a')
                            ->join('admin u', 'u.id = a.uid')
                            ->where('a.group_id', 3)
                            ->where('u.school_id', $params['school_id'])
                            ->count();
                        if ($count >= 11) {
                            exception('该学校管理员数量已经超过限额，不能再添加了！');
                        }
                    }

                    if (!Validate::is($params['password'], '\S{6,30}')) {
                        exception(__("Please input correct password"));
                    }

                    // 检查用户名是否重复
                    if (isset($params['username'])) {
                        $existsUsername = $this->model->where('username', $params['username'])->find();
                        if ($existsUsername) {
                            exception('用户名已存在，请选择其他用户名');
                        }
                    }

                    // 检查手机号是否重复
                    if (isset($params['mobile']) && !empty($params['mobile'])&&$params['mobile']!='') {
                        $existsMobile = $this->model->where('mobile', $params['mobile'])->find();
                        if ($existsMobile) {
                            exception('手机号已存在，请选择其他手机号');
                        }
                    }

                    $params['salt'] = Random::alnum();
                    $params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
                    $params['avatar'] = '/assets/img/avatar.png'; //设置新管理员默认头像。

                    // 如果选择了社区管理员，通过学校ID自动获取community_id和ocation_id
                    $isCommunityAdmin = false;
                    if (isset($params['group'])) {
                        $groupIds = (array)$params['group'];
                        // 查询选择的用户组中是否有社区管理员组
                        $communityGroups = Db::name('auth_group')
                            ->where('id', 'in', $groupIds)
                            ->where('name', 'like', '%社区%')
                            ->count();
                        $isCommunityAdmin = $communityGroups > 0;
                    }

                    if ($isCommunityAdmin) {
                        if (!empty($params['school_id'])) {
                            // 从eb_school_community表获取community_id和ocation_id
                            $schoolCommunity = Db::name('eb_school_community')
                                ->where('school_id', $params['school_id'])
                                ->find();

                            if ($schoolCommunity) {
                                $params['community_id'] = $schoolCommunity['community_id'];
                                $params['ocation_id'] = $schoolCommunity['ocation_id']; // 顶级教学点ID
                            }
                        }
                    }

                    // 如果不是超级管理员，自动继承当前用户的学校ID和社区ID
                    if (!$this->auth->isSuperAdmin()) {
                        $currentUser = $this->auth->getUserInfo();
                        if (!empty($currentUser['school_id']) && empty($params['school_id'])) {
                            $params['school_id'] = $currentUser['school_id'];
                        }
                        if (!empty($currentUser['community_id']) && empty($params['community_id'])) {
                            $params['community_id'] = $currentUser['community_id'];
                        }
                        // 继承地区信息
                        if (!empty($currentUser['province_id']) && empty($params['province_id'])) {
                            $params['province_id'] = $currentUser['province_id'];
                        }
                        if (!empty($currentUser['city_id']) && empty($params['city_id'])) {
                            $params['city_id'] = $currentUser['city_id'];
                        }
                        // 移除district_id处理，因为fa_admin表中不需要这个字段
                    }

                    $result = $this->model->save($params);
                    if ($result === false) {
                        exception($this->model->getError());
                    }


                    //过滤不允许的组别,避免越权
                    $group = array_intersect($this->childrenGroupIds, $group);
                    if (!$group) {
                        exception(__('The parent group exceeds permission limit'));
                    }

                    $dataset = [];
                    foreach ($group as $value) {
                        $dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
                    }
                    model('AuthGroupAccess')->saveAll($dataset);
                    Db::commit();
                    

                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get(['id' => $ids]);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if ($row->id != $this->auth->id && !in_array($row->id, $this->childrenAdminIds)) {
            $this->error(__('You have no permission'));
        }


        if ($this->request->isPost()) {
            $this->token();
            $params = $this->request->post("row/a");
            if ($params) {
                // 如果昵称为空，则用用户名
                if (empty($params['nickname']) && !empty($params['username'])) {
                    $params['nickname'] = $params['username'];
                }
                Db::startTrans();
                try {
                    // 教学点多选处理
                    if (isset($params['ocation_id']) && is_array($params['ocation_id'])) {
                        $params['ocation_id'] = implode(',', $params['ocation_id']);
                    }
                    // 如果选择了社区管理员，通过学校ID自动获取community_id和ocation_id
                    $isCommunityAdmin = false;
                    if (isset($params['group'])) {
                        $groupIds = (array)$params['group'];
                        // 查询选择的用户组中是否有社区管理员组
                        $communityGroups = Db::name('auth_group')
                            ->where('id', 'in', $groupIds)
                            ->where('name', 'like', '%社区%')
                            ->count();
                        $isCommunityAdmin = $communityGroups > 0;
                    }

                    if ($isCommunityAdmin) {
                        if (!empty($params['school_id'])) {
                            // 从eb_school_community表获取community_id和ocation_id
                            $schoolCommunity = Db::name('eb_school_community')
                                ->where('school_id', $params['school_id'])
                                ->find();

                            if ($schoolCommunity) {
                                $params['community_id'] = $schoolCommunity['community_id'];
                                $params['ocation_id'] = $schoolCommunity['ocation_id']; // 顶级教学点ID
                            }
                        }
                    }

                    if ($params['password']) {
                        if (!Validate::is($params['password'], '\S{6,30}')) {
                            exception(__("Please input correct password"));
                        }
                        $params['salt'] = Random::alnum();
                        $params['password'] = $this->auth->getEncryptPassword($params['password'], $params['salt']);
                    } else {
                        unset($params['password'], $params['salt']);
                    }
                    //这里需要针对username和email做唯一验证
                    $adminValidate = \think\Loader::validate('Admin');
                    $adminValidate->rule([
                        'username' => 'require|regex:\w{3,30}|unique:admin,username,' . $row->id,
                        'email'    => 'require|email|unique:admin,email,' . $row->id,
                        'mobile'   => 'regex:1[3-9]\d{9}|unique:admin,mobile,' . $row->id,
                        'password' => 'regex:\S{32}',
                    ]);
                    $result = $row->validate('Admin.edit')->save($params);
                    if ($result === false) {
                        exception($row->getError());
                    }

                    // 先移除所有权限
                    model('AuthGroupAccess')->where('uid', $row->id)->delete();

                    $group = $this->request->post("group/a");

                    // 过滤不允许的组别,避免越权
                    $group = array_intersect($this->childrenGroupIds, $group);
                    if (!$group) {
                        exception(__('The parent group exceeds permission limit'));
                    }

                    $dataset = [];
                    foreach ($group as $value) {
                        $dataset[] = ['uid' => $row->id, 'group_id' => $value];
                    }
                    model('AuthGroupAccess')->saveAll($dataset);
                    Db::commit();
                } catch (\Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $grouplist = $this->auth->getGroups($row['id']);
        $groupids = [];
        foreach ($grouplist as $k => $v) {
            $groupids[] = $v['id'];
        }
        $this->view->assign("row", $row);
        // 教学 много выбором
        if (isset($row['ocation_id']) && is_string($row['ocation_id'])) {
            $row['ocation_id'] = explode(',', $row['ocation_id']);
        }
        $this->view->assign("groupids", $groupids);
        return $this->view->fetch();
    }

    /**
     * 删除
     */
    public function del($ids = "")
    {
        if (!$this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ? $ids : $this->request->post("ids");
        if ($ids) {
            // 检查是否为学校管理员组用户，且只剩一个
            $schoolGroupId = 3; // 学校管理员组ID
            $schoolUserIds = model('AuthGroupAccess')->where('group_id', $schoolGroupId)->column('uid');
            $toDeleteIds = array_intersect($schoolUserIds, array_filter(explode(',', $ids)));
            if (count($schoolUserIds) === 1 && count($toDeleteIds) > 0) {
                $this->error('该学校只剩一个管理员用户，无法删除！');
            }
            $ids = array_intersect($this->childrenAdminIds, array_filter(explode(',', $ids)));
            // 避免越权删除管理员
            $childrenGroupIds = $this->childrenGroupIds;
            $adminList = $this->model->where('id', 'in', $ids)->where('id', 'in', function ($query) use ($childrenGroupIds) {
                $query->name('auth_group_access')->where('group_id', 'in', $childrenGroupIds)->field('uid');
            })->select();
            if ($adminList||$_SESSION['think']['admin']['username']=='admin') {
                if($_SESSION['think']['admin']['username']=='admin'){
                    model('Admin')->where('id', 'in', array_values($ids))->delete();
                    $this->success();
                }
                $deleteIds = [];
                foreach ($adminList as $k => $v) {
                    $deleteIds[] = $v->id;
                }
                $deleteIds = array_values(array_diff($deleteIds, [$this->auth->id]));
                if ($deleteIds) {
                    Db::startTrans();
                    try {
                        $this->model->destroy($deleteIds);
                        model('AuthGroupAccess')->where('uid', 'in', $deleteIds)->delete();
                        Db::commit();
                    } catch (\Exception $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    }
                    $this->success();
                }
                $this->error(__('No rows were deleted'));
            }
        }
        $this->error(__('You have no permission'));
    }

    /**
     * 批量更新
     * @internal
     */
    public function multi($ids = "")
    {
        // 管理员禁止批量操作
        $this->error();
    }

    /**
     * 下拉搜索
     */
    public function selectpage()
    {
        $this->dataLimit = 'auth';
        $this->dataLimitField = 'id';
        return parent::selectpage();
    }

    /**
     * 检查用户名是否重复 - Nice-Validator远程验证
     */
    public function checkUsername()
    {
        // 获取所有POST参数进行调试
        $allParams = $this->request->post();
        
        // 直接获取row[username]参数
        $username = $this->request->post('row.username', '');
        if (empty($username)) {
            $username = $this->request->post('username', '');
        }
        if (empty($username)) {
            $username = $this->request->get('username', '');
        }
        $id = $this->request->post('id', 0); // 编辑时传入当前记录ID

        // 记录调试日志
        $logData = [
            'all_params' => $allParams,
            'username' => $username,
            'id' => $id,
            'request_method' => $this->request->method(),
            'timestamp' => date('Y-m-d H:i:s')
        ];
        
        // 写入日志文件用于调试
        $logFile = dirname($_SERVER["DOCUMENT_ROOT"]) . '/checkUsername_debug.log';
        file_put_contents($logFile, json_encode($logData, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND);

        if (empty($username)) {
            $this->result('用户名不能为空', null, 0);
        }

        // 验证用户名格式
        if (!preg_match('/^[a-zA-Z0-9_]{3,30}$/', $username)) {
            $this->result('用户名格式不正确，只能包含字母、数字和下划线，长度3-30个字符', null, 0);
        }

        try {
            // 检查用户名是否已存在（排除当前记录）
            $query = $this->model->where('username', $username);
            if ($id > 0) {
                $query = $query->where('id', '<>', $id);
            }
            $exists = $query->find();

            if ($exists) {
                $this->result('用户名已存在，请选择其他用户名', null, 0);
            }

            // 返回成功
            $this->result('验证通过', 1, 1);
            
        } catch (\Exception $e) {
            // 记录异常日志
            $errorLogFile = dirname($_SERVER["DOCUMENT_ROOT"]) . '/checkUsername_error.log';
            file_put_contents($errorLogFile, '[' . date('Y-m-d H:i:s') . '] 数据库查询错误: ' . $e->getMessage() . "\n", FILE_APPEND);
            
            // 返回错误
            $this->result('数据库查询失败，请稍后重试', 0, 0);
        }
    }

    /**
     * 检查手机号是否重复 - Nice-Validator远程验证
     */
    public function checkMobile()
    {
        // 直接获取row[mobile]参数
        $mobile = $this->request->post('row.mobile', '');
        if (empty($mobile)) {
            $mobile = $this->request->post('mobile', '');
        }
        $id = $this->request->post('id', 0); // 编辑时传入当前记录ID

        if (empty($mobile)) {
            $this->result('手机号不能为空', null, 0);
        }

        // 验证手机号格式
        if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
            $this->result('手机号格式不正确', null, 0);
        }

        // 检查手机号是否已存在（排除当前记录）
        $query = $this->model->where('mobile', $mobile);
        if ($id > 0) {
            $query = $query->where('id', '<>', $id);
        }
        $exists = $query->find();

        // 如果是当前用户的手机号，允许通过
        $query2 = $this->model->where('mobile', $mobile)->where('id', '=', $id);
        $exist2 = $query2->find();
        if ($exist2) {
            $exists = null; // 当前用户的手机号，不算重复
        }

        if ($exists) {
            $this->result('手机号已存在，请选择其他手机号', null, 0);
        }

        // 返回成功，dataFilter会处理为空字符串
        $this->result('验证通过', null, 1);
    }

    /**
     * 根据昵称生成子教学点
     */
    public function generateOcationByNickname()
    {
        if (!$this->request->isPost()) {
            $this->error(__('Invalid parameters'));
        }

        // 获取当前管理员信息
        $admin = $_SESSION['think']['admin'];
        $nickname = $this->request->post('nickname', '');

        if (empty($nickname)) {
            $this->error('昵称不能为空');
        }

        // 获取当前管理员的教学点ID
        $ocationId = $admin['ocation_id'] ?? 0;
        if (empty($ocationId)) {
            $this->error('当前管理员没有关联的教学点');
        }

        // 获取当前教学点信息
        $parentOcation = Db::name('ocation')->where('id', $ocationId)->find();
        if (!$parentOcation) {
            $this->error('找不到关联的教学点');
        }

        // 开始事务
        Db::startTrans();
        try {
            // 创建子教学点
            $childOcationData = [
                'pid' => $ocationId,
                'name' => $nickname,
                'rel_type' => $parentOcation['rel_type'],
                'rel_id' => $parentOcation['rel_id'],
                'city_id' => $parentOcation['city_id'],
                'level' => $parentOcation['level'] + 1,
                'address' => $parentOcation['address'] ?? '',
                'address_lv' => $parentOcation['address_lv'] ?? '',
                'address_lv_octionlevel' => $parentOcation['address_lv_octionlevel'] ?? '',
                'school_location_type' => $parentOcation['school_location_type'] ?? '',
                'status' => 1,
                'weigh' => 0,
                'create_time' => time(),
                'update_time' => time()
            ];

            $childOcationId = Db::name('ocation')->insertGetId($childOcationData);

            // 更新当前管理员的ocation_id，指向新创建的子教学点
            Db::name('admin')->where('id', $admin['id'])->update(['ocation_id' => $childOcationId]);

            // 更新session中的ocation_id
            $_SESSION['think']['admin']['ocation_id'] = $childOcationId;

            // 提交事务
            Db::commit();

            $this->success('子教学点创建成功', '', ['ocation_id' => $childOcationId, 'ocation_name' => $nickname]);
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $this->error('创建子教学点失败：' . $e->getMessage());
        }
    }
}
